In [ ]:
import cv2
import numpy as np
from matplotlib import pyplot as plt
# Specify the image path
image_path = '/content/download (7).jpeg'
# Load the image
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
# Apply GaussianBlur to reduce noise and improve contour detection
image_blurred = cv2.GaussianBlur(image, (5, 5), 0)
# Apply adaptive thresholding to handle variations in lighting
binary_image = cv2.adaptiveThreshold(image_blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
# Find contours in the binary image
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Display the number of contours found on the binary image
print(f'Number of contours on binary image: {len(contours)}')
# Draw red bounding boxes around the contours and number them on the grayscale image
contour_image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) # Convert to 3 channels for color
for i, contour in enumerate(contours, 1):
x, y, w, h = cv2.boundingRect(contour)
cv2.rectangle(contour_image, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(contour_image, str(i), (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 1, cv2.LINE_AA)
# Display the original grayscale image with red bounding boxes and numbered contours
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Grayscale Image')
plt.axis('off')
plt.subplot(1, 2, 2)
plt.imshow(contour_image)
plt.title('Grayscale Image with Red Bounding Boxes \n and Numbered Contours')
plt.axis('off')
plt.show()
Number of contours on binary image: 230
In [ ]:
import cv2
import numpy as np
from matplotlib import pyplot as plt
# Specify the image path
image_path = '/content/download (7).jpeg'
# Load the image
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
# Apply GaussianBlur to reduce noise and improve contour detection
image_blurred = cv2.GaussianBlur(image, (5, 5), 0)
# Apply adaptive thresholding to handle variations in lighting
binary_image = cv2.adaptiveThreshold(image_blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
# Find contours in the binary image
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Set a threshold area to classify cells as "large cells"
threshold_area = 200 # Adjust this threshold according to your needs
# Draw red bounding boxes around large cells and number them on the grayscale image
contour_image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) # Convert to 3 channels for color
for i, contour in enumerate(contours, 1):
area = cv2.contourArea(contour)
if area > threshold_area:
x, y, w, h = cv2.boundingRect(contour)
cv2.rectangle(contour_image, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(contour_image, f"Large Cell {i}", (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1, cv2.LINE_AA)
# Display the original grayscale image with red bounding boxes around large cells
plt.figure(figsize=(8, 4))
plt.imshow(contour_image)
plt.title('Grayscale Image with Red Bounding Boxes around Large Cells')
plt.axis('off')
plt.show()
In [ ]:
import cv2
import numpy as np
from skimage import filters
from skimage.morphology import binary_opening
from skimage.util import invert
import matplotlib.pyplot as plt
# Specify the image path
image_path = '/content/download (7).jpeg'
# Load the image in color
im = cv2.imread(image_path, cv2.IMREAD_COLOR)
# Convert to grayscale
im1 = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
# Invert colors
im1_inv = invert(im1)
# Apply Otsu's thresholding to create a binary image
_, th_im = cv2.threshold(im1_inv, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Invert colors of the threshold image
th_im_inv = invert(th_im)
# Image opening to fill gaps in objects
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (4, 4))
res = cv2.morphologyEx(th_im_inv, cv2.MORPH_OPEN, kernel)
# Display the results
f, (ax0, ax1, ax2, ax3, ax4) = plt.subplots(1, 5, figsize=(15, 8))
ax0.imshow(invert(im), cmap='gray') # Original image
ax1.imshow(invert(im1), cmap='gray') # Grayscale
ax2.imshow(invert(th_im), cmap='gray') # Threshold image
ax3.imshow(invert(res), cmap='gray') # Otsu image with gap-filled objects
ax4.imshow(invert(res)) # Otsu image with gap-filled objects without cmap='gray'
# Hysteresis Thresholding
edges = filters.sobel(im1)
low = 0.1
high = 0.35
lowt = (edges > low).astype(int)
hight = (edges > high).astype(int)
hyst = filters.apply_hysteresis_threshold(edges, low, high)
# Display Hysteresis Thresholding results
f, (ax0, ax1, ax2, ax3, ax4, ax5) = plt.subplots(1, 6, figsize=(15, 8))
ax0.imshow(im) # Original image
ax1.imshow(im1) # Grayscale
ax2.imshow(edges, cmap='magma') # Sobel edges
ax3.imshow(lowt, cmap='magma') # Low threshold
ax4.imshow(hight, cmap='magma') # High threshold
ax5.imshow(hight + hyst, cmap='magma') # Hysteresis threshold
plt.tight_layout()
plt.show()
# Display Hysteresis Thresholding results without cmap='magma'
f, (ax0, ax1, ax2, ax3, ax4, ax5) = plt.subplots(1, 6, figsize=(15, 8))
ax0.imshow(im) # Original image
ax1.imshow(im1) # Grayscale
ax2.imshow(edges, cmap='gray') # Sobel edges
ax3.imshow(lowt, cmap='gray') # Low threshold
ax4.imshow(hight, cmap='gray') # High threshold
ax5.imshow(hight + hyst, cmap='gray') # Hysteresis threshold
plt.tight_layout()
plt.show()
In [ ]:
import cv2
import numpy as np
from skimage.measure import regionprops, label
from skimage.segmentation import clear_border
import matplotlib.pyplot as plt
# Specify the image path
image_path = '/content/download (7).jpeg'
# Load the image
image = cv2.imread(image_path)
# Convert the image to grayscale
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply Otsu's thresholding to create a binary image
_, binary_image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Apply clear_border to the binary image
binary_image_clear_border = clear_border(binary_image)
# Label connected components in the binary image
label_image = label(binary_image_clear_border)
# Find contours in the binary image after clear_border
contours, _ = cv2.findContours(binary_image_clear_border, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Display each prominent contour separately
for i, contour in enumerate(contours, 1):
# Calculate the area of the contour
area = cv2.contourArea(contour)
# Set a threshold for the minimum contour area (adjust as needed)
min_contour_area = 10
# If the contour area is larger than the threshold, compute additional properties
if area > min_contour_area:
# Compute region properties using skimage on the labeled image
regions = regionprops(label_image)
# Create a black image
contour_image = np.zeros_like(gray_image)
# Draw the current contour on the black image
cv2.drawContours(contour_image, [contour], -1, 255, thickness=cv2.FILLED)
# Plot the original image with the contour highlighted
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.imshow(contour_image, cmap='gray', alpha=0.5) # Overlay the contour image
plt.title(f'Contour {i}')
plt.show()
# Print region properties
for region in regions:
if region.label == i: # Find the corresponding region using the label
print(f"Label: {region.label}")
print(f"Area: {region.area}")
print(f"Equivalent Diameter: {region.equivalent_diameter}")
print(f"Minor Axis: {region.minor_axis_length}")
# Check if major_axis_length is not zero before calculating Aspect Ratio
if region.major_axis_length != 0:
aspect_ratio = region.minor_axis_length / region.major_axis_length
print(f"Major Axis: {region.major_axis_length}")
print(f"Length: {region.major_axis_length}") # Assuming this is the length
print(f"Width: {region.minor_axis_length}") # Assuming this is the width
print(f"Aspect Ratio: {aspect_ratio}")
else:
print("Major Axis is zero, cannot calculate Aspect Ratio")
print(f"Perimeter: {region.perimeter}")
print(f"Convex Hull Area: {region.convex_area}")
print(f"Solidity: {region.solidity}")
print(f"Bbox Area: {region.bbox_area}")
print(f"Extent: {region.extent}")
print(f"Eccentricity: {region.eccentricity}")
print(f"Orientation: {region.orientation}")
print(f"Inscribed Circle Diameter: {region.inertia_tensor_eigvals[1]}")
print(f"Circumscribed Circle Diameter: {2 * np.sqrt(region.area / np.pi)}")
print(f"Concavity: {region.area - region.convex_area}")
print(f"Hull Area: {region.convex_area}")
print(f"Martin's Diameter: {2 * np.sqrt(region.equivalent_diameter * region.perimeter / np.pi)}")
print("\n")
# You can use these properties as needed for further analysis or visualization.
Label: 4 Area: 11 Equivalent Diameter: 3.742410318509555 Minor Axis: 3.3525616208337774 Major Axis: 4.348458452036872 Length: 4.348458452036872 Width: 3.3525616208337774 Aspect Ratio: 0.7709770388316337 Perimeter: 9.82842712474619 Convex Hull Area: 13 Solidity: 0.8461538461538461 Bbox Area: 16 Extent: 0.6875 Eccentricity: 0.636862940980558 Orientation: 1.1659045405098132 Inscribed Circle Diameter: 0.7024793388429752 Circumscribed Circle Diameter: 3.742410318509555 Concavity: -2 Hull Area: 13 Martin's Diameter: 6.84341332648368
Label: 9 Area: 4 Equivalent Diameter: 2.256758334191025 Minor Axis: 2.0 Major Axis: 2.0 Length: 2.0 Width: 2.0 Aspect Ratio: 1.0 Perimeter: 4.0 Convex Hull Area: 4 Solidity: 1.0 Bbox Area: 4 Extent: 1.0 Eccentricity: 0.0 Orientation: 0.7853981633974483 Inscribed Circle Diameter: 0.25 Circumscribed Circle Diameter: 2.256758334191025 Concavity: 0 Hull Area: 4 Martin's Diameter: 3.3902176649900606
Label: 14 Area: 7 Equivalent Diameter: 2.985410660720923 Minor Axis: 1.9054711331003737 Major Axis: 4.155374705678736 Length: 4.155374705678736 Width: 1.9054711331003737 Aspect Ratio: 0.4585557905274719 Perimeter: 7.207106781186548 Convex Hull Area: 7 Solidity: 1.0 Bbox Area: 8 Extent: 0.875 Eccentricity: 0.8886656215775005 Orientation: -0.14572839723893355 Inscribed Circle Diameter: 0.2269262649424264 Circumscribed Circle Diameter: 2.985410660720923 Concavity: 0 Hull Area: 7 Martin's Diameter: 5.234046507870481
Label: 19 Area: 1 Equivalent Diameter: 1.1283791670955126 Minor Axis: 0.0 Major Axis is zero, cannot calculate Aspect Ratio Perimeter: 0.0 Convex Hull Area: 1 Solidity: 1.0 Bbox Area: 1 Extent: 1.0 Eccentricity: 0 Orientation: 0.7853981633974483 Inscribed Circle Diameter: 0.0 Circumscribed Circle Diameter: 1.1283791670955126 Concavity: 0 Hull Area: 1 Martin's Diameter: 0.0
Label: 21 Area: 10 Equivalent Diameter: 3.5682482323055424 Minor Axis: 3.098386676965933 Major Axis: 4.09878030638384 Length: 4.09878030638384 Width: 3.098386676965933 Aspect Ratio: 0.7559289460184543 Perimeter: 8.207106781186548 Convex Hull Area: 11 Solidity: 0.9090909090909091 Bbox Area: 12 Extent: 0.8333333333333334 Eccentricity: 0.6546536707079772 Orientation: 0.46364760900080604 Inscribed Circle Diameter: 0.5999999999999999 Circumscribed Circle Diameter: 3.5682482323055424 Concavity: -1 Hull Area: 11 Martin's Diameter: 6.106292882319363
Label: 23 Area: 9 Equivalent Diameter: 3.385137501286538 Minor Axis: 2.612014068307059 Major Axis: 4.25044367047193 Length: 4.25044367047193 Width: 2.612014068307059 Aspect Ratio: 0.6145273930937767 Perimeter: 7.621320343559642 Convex Hull Area: 10 Solidity: 0.9 Bbox Area: 12 Extent: 0.75 Eccentricity: 0.7888954830250753 Orientation: -0.6245228861991271 Inscribed Circle Diameter: 0.4264135933146246 Circumscribed Circle Diameter: 3.385137501286538 Concavity: -1 Hull Area: 10 Martin's Diameter: 5.731368396382551
Label: 24 Area: 3 Equivalent Diameter: 1.9544100476116797 Minor Axis: 1.3333333333333333 Major Axis: 2.3094010767585034 Length: 2.3094010767585034 Width: 1.3333333333333333 Aspect Ratio: 0.5773502691896256 Perimeter: 3.414213562373095 Convex Hull Area: 3 Solidity: 1.0 Bbox Area: 4 Extent: 0.75 Eccentricity: 0.816496580927726 Orientation: -0.7853981633974483 Inscribed Circle Diameter: 0.1111111111111111 Circumscribed Circle Diameter: 1.9544100476116797 Concavity: 0 Hull Area: 3 Martin's Diameter: 2.914796532718229
Label: 29 Area: 1 Equivalent Diameter: 1.1283791670955126 Minor Axis: 0.0 Major Axis is zero, cannot calculate Aspect Ratio Perimeter: 0.0 Convex Hull Area: 1 Solidity: 1.0 Bbox Area: 1 Extent: 1.0 Eccentricity: 0 Orientation: 0.7853981633974483 Inscribed Circle Diameter: 0.0 Circumscribed Circle Diameter: 1.1283791670955126 Concavity: 0 Hull Area: 1 Martin's Diameter: 0.0
Label: 30 Area: 13 Equivalent Diameter: 4.068428945128219 Minor Axis: 3.6794648440311994 Major Axis: 4.318667337728677 Length: 4.318667337728677 Width: 3.6794648440311994 Aspect Ratio: 0.8519908009322029 Perimeter: 10.242640687119284 Convex Hull Area: 13 Solidity: 1.0 Bbox Area: 16 Extent: 0.8125 Eccentricity: 0.523556754446835 Orientation: 0.7853981633974483 Inscribed Circle Diameter: 0.8461538461538463 Circumscribed Circle Diameter: 4.068428945128219 Concavity: 0 Hull Area: 13 Martin's Diameter: 7.2840747847508505
Label: 35 Area: 14 Equivalent Diameter: 4.222008245644752 Minor Axis: 4.038516251420292 Major Axis: 4.757011876926341 Length: 4.757011876926341 Width: 4.038516251420292 Aspect Ratio: 0.8489607249056751 Perimeter: 12.242640687119284 Convex Hull Area: 19 Solidity: 0.7368421052631579 Bbox Area: 25 Extent: 0.56 Eccentricity: 0.5284559466669203 Orientation: 0.5362402662922955 Inscribed Circle Diameter: 1.0193508445616128 Circumscribed Circle Diameter: 4.222008245644752 Concavity: -5 Hull Area: 19 Martin's Diameter: 8.112452176465847
Label: 62 Area: 3 Equivalent Diameter: 1.9544100476116797 Minor Axis: 0.0 Major Axis: 3.265986323710904 Length: 3.265986323710904 Width: 0.0 Aspect Ratio: 0.0 Perimeter: 1.0 Convex Hull Area: 3 Solidity: 1.0 Bbox Area: 3 Extent: 1.0 Eccentricity: 1.0 Orientation: 0.0 Inscribed Circle Diameter: 0.0 Circumscribed Circle Diameter: 1.9544100476116797 Concavity: 0 Hull Area: 3 Martin's Diameter: 1.5774765162267623
Label: 102 Area: 1 Equivalent Diameter: 1.1283791670955126 Minor Axis: 0.0 Major Axis is zero, cannot calculate Aspect Ratio Perimeter: 0.0 Convex Hull Area: 1 Solidity: 1.0 Bbox Area: 1 Extent: 1.0 Eccentricity: 0 Orientation: 0.7853981633974483 Inscribed Circle Diameter: 0.0 Circumscribed Circle Diameter: 1.1283791670955126 Concavity: 0 Hull Area: 1 Martin's Diameter: 0.0
Label: 108 Area: 11 Equivalent Diameter: 3.742410318509555 Minor Axis: 3.067356324605907 Major Axis: 4.346129984141888 Length: 4.346129984141888 Width: 3.067356324605907 Aspect Ratio: 0.7057672770483264 Perimeter: 9.414213562373096 Convex Hull Area: 11 Solidity: 1.0 Bbox Area: 12 Extent: 0.9166666666666666 Eccentricity: 0.7084437526351621 Orientation: -0.26303320949838166 Inscribed Circle Diameter: 0.5880421763812411 Circumscribed Circle Diameter: 3.742410318509555 Concavity: 0 Hull Area: 11 Martin's Diameter: 6.697655158652764
Label: 131 Area: 4 Equivalent Diameter: 2.256758334191025 Minor Axis: 1.2360679774997898 Major Axis: 3.23606797749979 Length: 3.23606797749979 Width: 1.2360679774997898 Aspect Ratio: 0.38196601125010515 Perimeter: 4.414213562373095 Convex Hull Area: 4 Solidity: 1.0 Bbox Area: 6 Extent: 0.6666666666666666 Eccentricity: 0.9241763718304448 Orientation: 1.0172219678978514 Inscribed Circle Diameter: 0.09549150281252629 Circumscribed Circle Diameter: 2.256758334191025 Concavity: 0 Hull Area: 4 Martin's Diameter: 3.5614287247956287
In [ ]:
import cv2
import numpy as np
from skimage.measure import regionprops, label
from skimage.segmentation import clear_border
import plotly.express as px
import plotly.graph_objects as go
# Specify the image path
image_path = '/content/download (7).jpeg'
# Load the image
image = cv2.imread(image_path)
# Convert the image to grayscale
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply Otsu's thresholding to create a binary image
_, binary_image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Apply clear_border to the binary image
binary_image_clear_border = clear_border(binary_image)
# Label connected components in the binary image
label_image = label(binary_image_clear_border)
# Find contours in the binary image after clear_border
contours, _ = cv2.findContours(binary_image_clear_border, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Create an empty DataFrame to store region properties
data = {
"Label": [],
"Area": [],
"Equivalent Diameter": [],
"Minor Axis": [],
"Major Axis": [],
"Length": [],
"Width": [],
"Aspect Ratio": [],
"Perimeter": [],
"Convex Hull Area": [],
"Solidity": [],
"Bbox Area": [],
"Extent": [],
"Eccentricity": [],
"Orientation": [],
"Inscribed Circle Diameter": [],
"Circumscribed Circle Diameter": [],
"Concavity": [],
"Hull Area": [],
"Martin's Diameter": []
}
# Display each prominent contour separately
for i, contour in enumerate(contours, 1):
# Calculate the area of the contour
area = cv2.contourArea(contour)
# Set a threshold for the minimum contour area (adjust as needed)
min_contour_area = 10
# If the contour area is larger than the threshold, compute additional properties
if area > min_contour_area:
# Compute region properties using skimage on the labeled image
regions = regionprops(label_image)
# Print region properties
for region in regions:
if region.label == i: # Find the corresponding region using the label
data["Label"].append(region.label)
data["Area"].append(region.area)
data["Equivalent Diameter"].append(region.equivalent_diameter)
data["Minor Axis"].append(region.minor_axis_length)
# Check if major_axis_length is not zero before calculating Aspect Ratio
if region.major_axis_length != 0:
aspect_ratio = region.minor_axis_length / region.major_axis_length
data["Major Axis"].append(region.major_axis_length)
data["Length"].append(region.major_axis_length) # Assuming this is the length
data["Width"].append(region.minor_axis_length) # Assuming this is the width
data["Aspect Ratio"].append(aspect_ratio)
else:
data["Major Axis"].append(None)
data["Length"].append(None)
data["Width"].append(None)
data["Aspect Ratio"].append(None)
data["Perimeter"].append(region.perimeter)
data["Convex Hull Area"].append(region.convex_area)
data["Solidity"].append(region.solidity)
data["Bbox Area"].append(region.bbox_area)
data["Extent"].append(region.extent)
data["Eccentricity"].append(region.eccentricity)
data["Orientation"].append(region.orientation)
data["Inscribed Circle Diameter"].append(region.inertia_tensor_eigvals[1])
data["Circumscribed Circle Diameter"].append(2 * np.sqrt(region.area / np.pi))
data["Concavity"].append(region.area - region.convex_area)
data["Hull Area"].append(region.convex_area)
data["Martin's Diameter"].append(2 * np.sqrt(region.equivalent_diameter * region.perimeter / np.pi))
# Create a DataFrame from the data
import pandas as pd
df = pd.DataFrame(data)
# Create a list to store Plotly figures
figs = []
# Example 1: Scatter plot - Area vs Perimeter
fig1 = px.scatter(df, x="Area", y="Perimeter", hover_data=["Label"], title="Area vs Perimeter")
figs.append(fig1)
# Example 2: Scatter plot - Aspect Ratio vs Eccentricity
fig2 = px.scatter(df, x="Aspect Ratio", y="Eccentricity", hover_data=["Label"], title="Aspect Ratio vs Eccentricity")
figs.append(fig2)
# Example 3: 3D Scatter plot - Major Axis vs Minor Axis vs Area
fig3 = px.scatter_3d(df, x="Major Axis", y="Minor Axis", z="Area", color="Label", size_max=10, title="Major Axis vs Minor Axis vs Area")
figs.append(fig3)
# Example 4: Histogram - Distribution of Areas
fig4 = px.histogram(df, x="Area", nbins=20, title="Distribution of Areas")
figs.append(fig4)
# Add more examples based on your preferences...
# Display the plots
for fig in figs:
fig.show()
In [ ]:
In [ ]: